using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Configuration;

namespace MediaBackup
{
    static class Application
    {
        // BrianSp: The main thread will block on this handle until this event is set.  Normally get's set on service stop.
        internal static ManualResetEvent s_End = new ManualResetEvent(false);

        public const string Name = "MediaBackup v1.2.1.0";

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            // BrianSp: This app can be run as a command line utility if you pass any argument to it.  Otherwise it assumes
            // it is executing in the context of an installed windows service.
            if (args.Length == 0)
            {
                // More than one user Service may run within the same process. To add
                // another service to this process, change the following line to
                // create a second service object. For example,
                //
                //   new ServiceBase[] {new Service1(), new MySecondUserService()};
                //
                ServiceBase.Run(new ServiceBase[] { new Service() });
            }
            else if (args.Length == 1)
            {
                if (args[0] == "/console" || args[0] == "/c")
                    Run();
                else
                    Help();
            }
            else
            {
                Help();
            }
        }

        public static void Help()
        {
            Console.WriteLine(Name + " usage:");
            Console.WriteLine("    /console or /c - Run as a console app");
            Console.WriteLine("    (no args) - Run as a service");
            Console.WriteLine("    (anything else) - Display this help text");
        }

        // BrianSp: This is the main entry point for the main thread.  Spins up worker threads and waits for signal to stop.
        public static void Run()
        {
            try
            {
                string logFile = ConfigurationManager.AppSettings["Log File"];
                if (logFile != null)
                    Log.SetLogFile(logFile);

                // $$BrianSp: It would be nice to read the version from the assembly attribute.
                Log.WriteLine(Name + " started");

                Thread thread1 = new Thread(new ThreadStart(Pipeline.RunFromAppConfig));
                thread1.Start();

                Thread thread2 = new Thread(new ThreadStart(Downloader.RunFromAppConfig));
                thread2.Start();

                s_End.WaitOne();
                thread1.Abort();
                thread2.Abort();
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception e)
            {
                Log.Write(e);
                throw;
            }
            finally
            {
                // $$BrianSp: It would be nice to read the version from the assembly attribute.
                Log.WriteLine(Name + " stopped");
            }
        }
    }
}